﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using GMap.NET;
using GMap.NET.MapProviders;
using GMap.NET.WindowsPresentation;
using System.Collections.ObjectModel;
using RZD_maps.Modules.Map.ViewModel;
using System.Threading;
using System.Windows.Threading;
using System.ComponentModel;
using System.Diagnostics;

using StaffLibrary;
using RZD_maps.Modules.Map.CustomMarkers;

namespace RZD_maps.Modules.Map.Views
{

    /// <summary>
    /// Логика взаимодействия для MapsView.xaml
    /// </summary>
    public partial class MapsView : UserControl, IMapsView
    {
        private VMMap view_model;

        public MapsView()
        {
            InitializeComponent();
            MainMap.Zoom = 13;
            if (null != OpenCycleTransportMapProvider.Instance)
            {
                MainMap.MapProvider = OpenCycleTransportMapProvider.Instance;
            }
            //transport.DoWork += new DoWorkEventHandler(transport_DoWork);
            //transport.ProgressChanged += new ProgressChangedEventHandler(transport_ProgressChanged);
            //transport.WorkerSupportsCancellation = true;
            //transport.WorkerReportsProgress = true;
            //transport.RunWorkerAsync();

            //GeoCoderStatusCode status = GeoCoderStatusCode.Unknow;
            //List<PointAndInfo> objects = new List<PointAndInfo>();
            //{
            //    string area = "Орехово-Зуево";
            //    PointLatLng? pos = GMapProviders.GoogleMap.GetPoint("Россия, Московская область, " + area, out status);
            //    if (pos != null && status == GeoCoderStatusCode.G_GEO_SUCCESS)
            //    {
            //        objects.Add(new PointAndInfo(pos.Value, area));
            //    }
            //}

            //// add objects to zone
            //foreach (var o in objects)
            //{
            //    GMapMarker it = new GMapMarker(o.Point);
            //    {
            //        it.ZIndex = 55;
            //        var s = new CustomMarkerDemo(this, it, o.Info );
            //        it.Shape = s;
            //    }

            //    MainMap.Markers.Add(it);
            //}
        }

        public MapsView(VMMap view_model)
            : this()
        {
            this.view_model = view_model;
            view_model.View = this;
        }

        public void SetMarkerLayerVisibility(bool visible)
        {
            
        }

        public void SetRoadLayerVisibility(bool visible)
        {
            
        }

        public void SetTrainLayerVisibility(bool visible)
        {
            
        }


        public void SetPosition(double lat, double lng)
        {
            MainMap.Position = new PointLatLng(lat, lng);
        }


        public GMap.NET.WindowsPresentation.GMapControl GetMapControl()
        {
            return MainMap;
        }


        public event EventHandler SetLayers = delegate { };

        public readonly ObservableCollection<GMapMarker> Markers = new ObservableCollection<GMapMarker>();


        readonly List<VehicleData> train = new List<VehicleData>();
        readonly Dictionary<int, GMapMarker> trainMarkers = new Dictionary<int, GMapMarker>();

        bool firstLoadTrasport = true;

        BackgroundWorker transport = new BackgroundWorker();

        public void transport_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            using (Dispatcher.DisableProcessing())
            {
                lock (train)
                {
                    foreach (VehicleData d in train)
                    {
                        GMapMarker marker;

                        if (!trainMarkers.TryGetValue(d.Id, out marker))
                        {
                            marker = new GMapMarker(new PointLatLng(d.Lat, d.Lng));
                            marker.Tag = d.Id;

                            var v = new RectangleVisual(marker, Brushes.Blue);//CircleVisual(marker, Brushes.Blue);
                            {
                                v.Stroke = new Pen(Brushes.Gray, 2.0);
                            }
                            marker.Shape = v;

                            trainMarkers[d.Id] = marker;
                            MainMap.Markers.Add(marker);
                        }
                        else
                        {
                            marker.Position = new PointLatLng(d.Lat, d.Lng);
                            //var shape = (marker.Shape as CircleVisual);
                            var shape = (marker.Shape as RectangleVisual);
                            {
                                shape.Text = d.Line;
                                shape.Angle = d.Bearing;
                                shape.Tooltip.SetValues("Train", d);

                                if (shape.IsChanged)
                                {
                                    shape.UpdateVisual(false);
                                }
                            }
                        }
                    }
                }

                if (firstLoadTrasport)
                {
                    firstLoadTrasport = false;
                }
            }
        }

        void transport_DoWork(object sender, DoWorkEventArgs e)
              {
                 while(!transport.CancellationPending)
                 {
                    try
                    {

                       lock(train)
                       {
                          Stuff.GetTransportData(TransportType.Train, string.Empty, train);
                       }

                       transport.ReportProgress(100);
                    }
                    catch(Exception ex)
                    {
                       Debug.WriteLine("transport_DoWork: " + ex.ToString());
                    }
                    Thread.Sleep(3333);
                 }
                 trainMarkers.Clear();
              }

    }


    public struct PointAndInfo
    {
        public PointLatLng Point;
        public string Info;

        public PointAndInfo(PointLatLng point, string info)
        {
            Point = point;
            Info = info;
        }
    }
}
